/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package co.dzgroup.votacion.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.apache.log4j.Logger;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;

/**
 * Clase util para manejar formatos y metodos comunes para el aplicativo
 * @author Lucho
 */
public class Formato{

    private static Logger log=Logger.getLogger(Formato.class);
    private static String CLAVE_ENCRIPTAR="DzGroup";

    /**
     * Método para cambiar un valor en caso que sea nulo
     * @param texto
     * @param valorSiEsNulo
     * @return texto
     */
    public static String cambiarSiEsNull(String texto, String valorSiEsNulo){
        String resultado;
        if(texto==null){
            resultado=valorSiEsNulo;
        }else{
            resultado=texto;
        }
        return resultado;
    }

    /**
     * Método para convertir una fecha Date a una fecha SQL
     * @param fecha
     * @return Fecha Sql
     */
    public static java.sql.Date convertirFechaDateASQL(Date fecha){
        java.sql.Date fechaSQL=new java.sql.Date(fecha.getTime());
        return fechaSQL;
    }

    /**
     * Método que devuelve la edad en años de una fecha de nacimiento dererminada
     * @param fechaNacimiento
     * @return Edad en años
     */
    public static int edadEnAnos(Date fechaNacimiento){
        int diferencia = -1;
        try{
            Calendar fechaNac =Calendar.getInstance();
            fechaNac.setTime(fechaNacimiento);
            Calendar fechaActual = Calendar.getInstance();
            diferencia = (fechaActual.get(Calendar.YEAR) - fechaNac.get(Calendar.YEAR));
            int mesAct = fechaActual.get(Calendar.MONTH);
            int mesNac = fechaNac.get(Calendar.MONTH);
            if (mesAct < mesNac){
                diferencia--;
            }else if (mesAct == mesNac){
                int diaAct = fechaActual.get(Calendar.DAY_OF_MONTH);
                int diaNac = fechaNac.get(Calendar.DAY_OF_MONTH);
                if (diaAct < diaNac){
                    diferencia--;
                }
            }
        }catch (Exception e){
            diferencia = -1;
        }
        return diferencia;
    }

    /**
     * Método para crear un archivo con una arreglo en una ruta especifica.
     * @param fileBytes
     * @param archivoDestino
     * @return TRUE si se genero el archivo, de lo contrario devuelve FALSE
     */
    public static boolean escribirArchivo(byte[] fileBytes, String archivoDestino){
       boolean correcto = false;
       try {
         File archivo=new File(archivoDestino);
         archivo.createNewFile();
         OutputStream out = new FileOutputStream(archivoDestino);
         out.write(fileBytes);
         out.close();
         correcto = true;
       }catch (Exception e) {
        log.error("Error en el método Formato.escribirArchivo:"+e.getMessage());
       }
       return correcto;
    }

    /**
     * Método para convertir cada palabra de la cadena en mayuscula
     * @param cadena
     * @return Cadena en formato propper Case
     */
    public static String properCase(String cadena){
        String fixedProperCase = "";
        if (cadena != null && !cadena.equals("")){
            String u = cadena.toUpperCase();

            String twoPast = " ";
            String lastChar = " ";
            String specialChars = " ~`@#$%^&*()_-+={}[]|\\:;\"'<>,.?/1234567890";
            for (int i = 0; i < cadena.length(); i++){
                String char1 = "" + u.charAt(i);
                if (specialChars.indexOf(lastChar) != -1){
                    if ((lastChar == null ? "\'" == null : lastChar.equals("\'")) && (!twoPast.equals("D"))){
                        char1 = char1.toLowerCase();
                    }else if (char1.equals("Y")){
                        char1 = char1.toLowerCase();
                    }
                }else{
                    char1 = char1.toLowerCase();
                }
                fixedProperCase = fixedProperCase + "" + char1;
                twoPast = lastChar;
                lastChar = char1;
            }
        }
        fixedProperCase = fixedProperCase.trim();
        return fixedProperCase;
    }

    /**
     * Metodo que retorna la ip del equipo
     * @return
     * @throws UnknownHostException
     */
    public static String getIpEquipo() throws UnknownHostException{
        InetAddress localHost = InetAddress.getLocalHost();
        return localHost.getHostAddress();
    }

    /**
     * Método encargado de ejecutar la operación de encriptar un texto,
     * de acuerdo a la clave ingresada.
     * @param cadena
     * @param clave
     * @return Texto encriptado
     */
    public static String encrypt(String cadena,String clave) {
        StandardPBEStringEncryptor s = new StandardPBEStringEncryptor();
        s.setPassword(clave);
        String encriptada= s.encrypt(cadena);
        String encode="";
        try {
            encode = URLEncoder.encode(encriptada, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            log.error("Error en el método Formato.encrypt"+ex.getMessage());
        }
        s.encrypt(cadena);
        return encode;
    }

    /**
     * Método para llamar el método encargado de encriptar un texto.
     * @param cadena
     * @return
     */
    public static String encriptarTexto(String cadena) {
        return encrypt(cadena,CLAVE_ENCRIPTAR);
    }

    /**
     * Método encargado de ejecutar la operación de desencriptar un texto,
     * de acuerdo a la clave ingresada.
     * @param cadena
     * @param clave
     * @return
     */
    public static String decrypt(String cadena,String clave) {
        StandardPBEStringEncryptor s = new StandardPBEStringEncryptor();
        s.setPassword(clave);
        String devuelve = "";
        try {
            devuelve = s.decrypt(cadena);
        } catch (Exception e) {
            log.error("Error en el método Formato.decrypt:"+e.getMessage());
        }
        return devuelve;
    }

    /**
     * Método para llamar el método encargado de desencriptar un texto.
     * @param cadena
     * @return
     */
    public static String desencriptarTexto(String cadena) {
        return decrypt(cadena,CLAVE_ENCRIPTAR);
    }

    /**
     * Método para una fecha Date a String en el formato estanda yyyy-MM-dd
     * @param fecha
     * @return
     */
    public static String fechaDateFormatoEstandar(Date fecha){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        return simpleDateFormat.format(fecha);
    }

    /**
     * Método para una fecha Date a String en el formato estanda yyyy-MM-dd
     * @param fecha
     * @return
     */
    public static String fechaDateFormatoHora(Date fecha){
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(fecha);
    }
}
